﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->comboBox->clear();
    //通过QSerialPortInfo查找可用串口
//    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
//    {
//        ui->comboBox->addItem(info.portName());
//    }
//    ui->comboBox_2->addItem("9600",0);
//    ui->comboBox_3->addItem("8", 8);
//    ui->comboBox_4->addItem("NO", 0);
//    ui->comboBox_5->addItem("1位", 1);
//    ui->comboBox_5->addItem("2位", 2);

    //连接信号和槽
    QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);



}

MainWindow::~MainWindow()
{
    m_bolIsOpen = false;
    delete ui;
}

void MainWindow::serialPort_readyRead()
{
    //从接收缓冲区中读取数据
    QByteArray buffer = serial.readAll();
    //从界面中读取以前收到的数据
    QString recv = ui->textEdit->toPlainText();
    recv += QString(buffer);
    //清空以前的显示
    ui->textEdit->clear();
    //重新显示
    ui->textEdit->append(recv);
}

void MainWindow::on_pushButton_clicked()
{
    ui->textEdit->clear();
}

//发送数据
void MainWindow::on_pushButton_2_clicked()
{
    write();
    //获取界面上的数据并转换成utf8格式的字节流
//    QByteArray data = ui->textEdit_2->toPlainText().toUtf8();
//    serial.flush();
//    serial.write(data);
}

//监测端口
void MainWindow::on_pushButton_3_clicked()
{
    ui->comboBox->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->comboBox->addItem(info.portName());
    }
}

void MainWindow::on_pushButton_4_clicked()
{
    string comm= "COM1";
    BOOL bIsOpen = gSerialPort.OpenComm(1);
    if (bIsOpen)
    {
        BOOL bRet = gSerialPort.SetCommState(1, 9600, 0, 8, 0);
        if (!bRet)
        {
            gSerialPort.CloseComm(1);
            QMessageBox::about(this,"提示","设置串口属性失败！!");
            return;
        }

        bRet = gSerialPort.SetupComm(1, 1024, 1024);
        if (!bRet)
        {
            gSerialPort.CloseComm(1);
            QMessageBox::about(this,"提示","设置串口输入输出缓冲区失败！!");
            return;
        }

        bRet = gSerialPort.PurgeComm(1, PURGE_RXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
        if (!bRet)
        {
            gSerialPort.CloseComm(1);
            QMessageBox::about(this,"提示","无法清除串口的错误状态！!");
            return;
        }

        bRet = gSerialPort.SetCommMask(1, EV_RXCHAR);
        if (!bRet)
        {
            gSerialPort.CloseComm(1);
            QMessageBox::about(this,"提示","设置串口时间出错！!");
            return;
        }

        gSerialPort.StartComm(1);
        QtConcurrent::run(this, &MainWindow::DispText);
        bIsOpen = TRUE;
    }

    comm= "COM3";
    bIsOpen = gSerialPort.OpenComm(3);
    if (bIsOpen)
    {
        BOOL bRet = gSerialPort.SetCommState(3, 9600, 0, 8, 0);
        if (!bRet)
        {
            gSerialPort.CloseComm(3);
            QMessageBox::about(this,"提示","设置串口属性失败！!");
            return;
        }

        bRet = gSerialPort.SetupComm(3, 1024, 1024);
        if (!bRet)
        {
            gSerialPort.CloseComm(3);
            QMessageBox::about(this,"提示","设置串口输入输出缓冲区失败！!");
            return;
        }

        bRet = gSerialPort.PurgeComm(3, PURGE_RXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
        if (!bRet)
        {
            gSerialPort.CloseComm(3);
            QMessageBox::about(this,"提示","无法清除串口的错误状态！!");
            return;
        }

        bRet = gSerialPort.SetCommMask(3, EV_RXCHAR);
        if (!bRet)
        {
            gSerialPort.CloseComm(3);
            QMessageBox::about(this,"提示","设置串口时间出错！!");
            return;
        }

        gSerialPort.StartComm(3);
        QtConcurrent::run(this, &MainWindow::DispText);
        bIsOpen = TRUE;
    }
    //open();
//    QString str = ui->pushButton_4->text();
//    if(str==QString("打开串口"))
//    {
//        //设置串口名
//        serial.setPortName(ui->comboBox->currentText());
//        //设置波特率
//        serial.setBaudRate(ui->comboBox_2->currentText().toInt());
//        //设置数据位数
//        switch(ui->comboBox_3->currentIndex())
//        {
//        case 8: serial.setDataBits(QSerialPort::Data8); break;
//        default: break;
//        }
//        //设置奇偶校验
//        switch(ui->comboBox_4->currentIndex())
//        {
//        case 0: serial.setParity(QSerialPort::NoParity); break;
//        default: break;
//        }
//        //设置停止位
//        switch(ui->comboBox_5->currentIndex())
//        {
//        case 1: serial.setStopBits(QSerialPort::OneStop); break;
//        case 2: serial.setStopBits(QSerialPort::TwoStop); break;
//        default: break;
//        }
//        //设置流控制
//        serial.setFlowControl(QSerialPort::NoFlowControl);
//        //打开串口
//        if(!serial.open(QIODevice::ReadWrite))
//        {
//            QMessageBox::about(this,"提示","无法打开串口!");
//            return;
//        }
//        //下拉菜单控件失能
//        ui->comboBox->setEnabled(false);
//        ui->comboBox_2->setEnabled(false);
//        ui->comboBox_3->setEnabled(false);
//        ui->comboBox_4->setEnabled(false);
//        ui->comboBox_5->setEnabled(false);
//        ui->pushButton_4->setText(QString("关闭串口"));
//        //发送按键使能
//        ui->pushButton_2->setEnabled(true);
//    }
//    else
//    {
//        //关闭串口
//        serial.close();
//        //下拉菜单控件使能
//        ui->comboBox->setEnabled(true);
//        ui->comboBox_2->setEnabled(true);
//        ui->comboBox_3->setEnabled(true);
//        ui->comboBox_4->setEnabled(true);
//        ui->comboBox_5->setEnabled(true);
//        ui->pushButton_4->setText(QString("打开串口"));
//        //发送按键失能
//        ui->pushButton_2->setEnabled(false);
//    }
}



DWORD WINAPI  ClockThreadProc(LPVOID IParam)
{
    MainWindow *pDlg   = (MainWindow*)(IParam);
    while(pDlg->m_bolIsOpen)
    {
        pDlg->read();
    }
    return 0;
}

void MainWindow::open()
{
    int n = ui->comboBox->currentIndex();
    QString szqFileName = QString("COM%1").arg(n+1);
    TCHAR szPortName[64];
    TCHAR *p = szPortName;
    p = (wchar_t*)szqFileName.utf16();
    handle = CreateFile(p, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0,NULL);

    if (handle == INVALID_HANDLE_VALUE)
    {
        QMessageBox::warning(this,"警告","Error in CreateFile");
        return;
    }
    DCB dcb;
    GetCommState(handle, &dcb);
    dcb.BaudRate = 9600;
    dcb.ByteSize = 8;
    dcb.fParity = FALSE;
    dcb.StopBits = ONESTOPBIT;
    BOOL isTure = SetCommState(handle ,&dcb);
    if (isTure == FALSE)
    {
        QMessageBox::warning(this,"警告","串口参数设置失败");
        return;
    }

    //设置串口超时
    COMMTIMEOUTS timeouts;
    timeouts.ReadIntervalTimeout = 2000;//读取间隔超时设置为2s
    isTure = SetCommTimeouts(handle, &timeouts);
    if (isTure == FALSE)
    {
        QMessageBox::warning(this,"警告","串口超时设置失败");
        return;
    }

    //设置各缓冲区的大小
    SetupComm(handle, 1024, 1024);
    //清除缓冲区的内容
    isTure = PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_RXCLEAR | PURGE_RXCLEAR);
    if (isTure == FALSE)
    {
        QMessageBox::warning(this,"警告","清除缓冲区操作失败");
        return;
    }

    m_bolIsOpen = true;
    unsigned threadid = 100;

    //HANDLE hThread1 = CreateThread(NULL, 0, ClockThreadProc, this, 0, NULL);
    QtConcurrent::run(this, &MainWindow::read);
}

void MainWindow::write()
{
    OVERLAPPED over;
    memset(&over, 0, sizeof(OVERLAPPED));
    over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    DWORD	dwError;
    COMSTAT	comstat;
    ClearCommError(handle, &dwError, &comstat);

    //UpdateData(true);
    QString str = ui->textEdit_2->toPlainText();
    DWORD	dword;
    BOOL isTrue = WriteFile(handle, (wchar_t*)str.utf16(), str.length(), &dword, &over);
    if (!isTrue)
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            //WaitForSingleObject(over.hEvent, 1000);
        }
    }
    string sasd = str.toStdString();
    gSerialPort.WriteFile(1, sasd);
    gSerialPort.WriteFile(3, sasd);
}

void MainWindow::read()
{
    while(m_bolIsOpen)
    {
        Sleep(5);
        OVERLAPPED	over;
        memset(&over, 0, sizeof(OVERLAPPED));
        over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);


        DWORD	dwError;
        COMSTAT	comstat;
        ClearCommError(handle, &dwError, &comstat);
        char buff[1024];
        DWORD	dword;
        BOOL isTrue = ReadFile(handle, buff, 200, 0, &over);
        QByteArray receiveData = QByteArray((char *)buff);
        QString str = QString::fromLocal8Bit(buff,1024);

        if(isTrue)
        {
            if (receiveData != "")
            {
                if (receiveData.startsWith("ST") || receiveData.startsWith("UT"))
                {
                    QString string;
                    string.prepend(receiveData);
                    ui->textEdit->append(string);
                }
                else
                {
                    PurgeComm(handle, PURGE_RXCLEAR);
                }

            }
        }

    }

}


void MainWindow::DispText()
{
    string str;
    while(true)
    {
        Sleep(20);
        if(gSerialPort.ReceivedSize(1) > 0)
        {
            str = gSerialPort.ReceivedPop(1);
            //ui->textEdit->append(QString("1:" + QString::fromLocal8Bit(str.c_str())));
            continue;
        }
        if(gSerialPort.ReceivedSize(3) > 0)
        {
            str = gSerialPort.ReceivedPop(3);
            //ui->textEdit->append(QString("3:" + QString::fromLocal8Bit(str.c_str())));
            continue;
        }
    }
}


